package org.act.BPEL2Automata.automata.module;

import java.util.LinkedList;

/**
 * 
 * Object <b>TransitionFunction</b> holds a list of <b>TransitionRule</b>s.
 * @author baoxiwu<bb@feijiao.info>,ACT,Beihang University
 * @version 0.9.0
 * @since 2010-03-23
 * 
 */
public class TransitionFunction {
	//<object>TransitionFunction</object> consists of a number of 
	//<object>TransitionRule</object>s
	private LinkedList<TransitionRule> tRule = new LinkedList<TransitionRule>();
	
	public TransitionFunction(){
	//empty	
	}

	
	//add a TransitionRule to the TransitionFunction
	//in the form of 3-tuple : <StartState,Message,EndState>
	public void add(State start,Message mes,State end){
		//TODO make a decision,we need to check the added TransitionRule's uniqueness.
		//System.err.println("TESTING isUnique() method : " + this.isUnique(start, mes, end));
		TransitionRule tr = new TransitionRule(start,mes,end);
		this.tRule.add(tr);
	}
	
	public void add(TransitionRule tr){
		this.tRule.add(tr);
	}
	
	
	public void addAll(LinkedList<TransitionRule> trs){
		this.tRule.addAll(trs);
	}
	
	//remove a TransitionRule from the TransitionFunction
	public void remove(TransitionRule tr){
		this.tRule.remove(tr);
	}
	
	public LinkedList<TransitionRule> getTransitionRuleList(){
		return this.tRule;
	}
	
	//get TransitionRules by a start state.
	public LinkedList<TransitionRule> getByStartState(State start){
		LinkedList<TransitionRule> list = new LinkedList<TransitionRule>();
		
		for(int i = 0; i < this.tRule.size(); i++){
			if(this.tRule.get(i).getStartState() == start){
				list.add(this.tRule.get(i));
			}
		}
		
		return list;
	}
	
	/*
	 * TODO TESTING WANTED.ONLY ONE END STATE SELECTED BY START STATE AND MESSAGE?
	 * get the end state by a start state and a message.
	 * 
	 */	
	public State getByStartStateAndMessage(State start,Message mes){
		State state = null;
		
		for(int i = 0; i < this.tRule.size(); i++){
			if((this.tRule.get(i).getStartState() == start) && 
					(this.tRule.get(i).getMessage() == mes)){
				state = this.tRule.get(i).getEndState();
				
				break;
			}
		}
		
		return state;
	}
	
	private boolean isUnique(State start,Message mes,LinkedList<State> end){
		//TODO IS IT NECESSARY?!
		System.err.println(start.getID() + "_" + mes.getID() + "->" + end.get(0).getID());
		
		State state = this.getByStartStateAndMessage(start, mes);
		
		
		for(int i = 0; i < end.size(); i++){
			if(state == end.get(i)){
				return false;
			}
		}
		return true;
	}
}
